﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using Microsoft.Win32;
using ClosedXML.Excel;
using SPI_TOOLS.CustomControl;
using SPI_TOOLS.Models;
using SPI_TOOLS.Services;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Data;
using DocumentFormat.OpenXml.Spreadsheet;


namespace SPI_TOOLS.ViewModels
{
    public class PanelStatisticsViewModel : ViewModelBase
    {
        public PanelStatisticsViewModel()
        {
            Operators.Add("导出报表");
            //Operators.Add("修改产品分辨率");
        }
        #region 属性
        private DateTime startTime = DateTime.Now;
        public DateTime StartTime
        {
            get { return startTime; }
            set { startTime = value; RaisePropertyChanged(nameof(StartTime)); }
        }

        private int startTime_hour = 0;
        public int StartTime_hour
        {
            get { return startTime_hour; }
            set { startTime_hour = value; RaisePropertyChanged(nameof(StartTime_hour)); }
        }

        private DateTime endTime = DateTime.Now;
        public DateTime EndTime
        {
            get { return endTime; }
            set { endTime = value; RaisePropertyChanged(nameof(EndTime)); }
        }
        private int endTime_hour = 0;
        public int EndTime_hour
        {
            get { return endTime_hour; }
            set { endTime_hour = value; RaisePropertyChanged(nameof(EndTime_hour)); }
        }

        private string serachMachineName = "";
        public string SerachMachineName
        {
            get { return serachMachineName; }
            set { serachMachineName = value; RaisePropertyChanged(nameof(SerachMachineName)); }
        }

        private List<int> hourList = Enumerable.Range(0, 24).ToList();
        public List<int> HourList
        { get { return hourList; } }


        private MachineStatisModel? currentStatisModel;
        public MachineStatisModel? CurrentStatisModel
        {
            get { return currentStatisModel; }
            set { currentStatisModel = value; RaisePropertyChanged(nameof(CurrentStatisModel)); }
        }

        private string currentMachineName = "";
        public string CurrentMachineName
        {
            get { return currentMachineName; }
            set { 
                currentMachineName = value; 
                RaisePropertyChanged(nameof(CurrentMachineName));
                if (currentMachineName != null)
                {
                    if (MachineStatisInfos.ContainsKey(currentMachineName))
                        CurrentStatisModel = MachineStatisInfos[currentMachineName];
                }
                else
                {
                    CurrentStatisModel = null;
                }
            }
        }


        public Dictionary<string, MachineStatisModel> MachineStatisInfos = new Dictionary<string, MachineStatisModel>();

        private ObservableCollection<string> machineNameList = new ObservableCollection<string>();
        public ObservableCollection<string> MachineNameList
        {
            get { return machineNameList; }
            set { machineNameList = value; RaisePropertyChanged(nameof(MachineNameList)); }
        }

        private ObservableCollection<string> operators = new ObservableCollection<string>();
        public ObservableCollection<string> Operators
        {
            get { return operators; }
            set { operators = value; RaisePropertyChanged(nameof(Operators)); }
        }

        private RelayCommand<string>? operatorCommand;
        public RelayCommand<string> OperatorCommand
        {             
            get
            {
                if (operatorCommand == null)
                {
                    operatorCommand = new RelayCommand<string>(OperatorClick);
                }
                return operatorCommand;
            }
        }
        private void OperatorClick(string obj)
        {
            switch (obj)
            {
                case "导出报表":
                    string filePath = ShowSaveFileDialog($"报表_{DateTime.Now.ToString("yyyyMMdd_HHmmss")}.xlsx");
                    if (!string.IsNullOrEmpty(filePath))
                    {
                        // 在这里调用导出Excel的方法，例如：
                        ExportReport(filePath);
                        MessageBox.Show($"文件将保存至：{filePath}", "保存成功", MessageBoxButton.OK, MessageBoxImage.Information);
                    }
                    break;
                case "修改产品分辨率":
                    //ProductInfoWindow pw = new ProductInfoWindow(this);
                    //pw.ShowDialog();
                    break;
            }
        }

        private void ExportReport(string filepath)
        {
            using (var workbook = new XLWorkbook())
            {
                foreach (var m in MachineStatisInfos)
                {
                    var worksheet = workbook.Worksheets.Add(m.Key);
                    ExportToExcel(m.Value.GenerateTable(), worksheet);
                }

                workbook.SaveAs(filepath);
            }
        }
        private string ShowSaveFileDialog(string defaultFileName)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            // 设置默认文件名
            saveFileDialog.FileName = defaultFileName;

            // 设置文件类型过滤器
            saveFileDialog.Filter = "Excel文件 (*.xlsx)|*.xlsx|所有文件 (*.*)|*.*";

            // 设置默认文件类型过滤器索引（从1开始）
            saveFileDialog.FilterIndex = 1;

            // 如果用户没有输入扩展名，自动添加默认扩展名
            saveFileDialog.DefaultExt = "xlsx";

            // 当用户输入的文件名没有扩展名时，是否自动添加扩展名
            saveFileDialog.AddExtension = true;

            // 如果文件已存在，提示覆盖
            saveFileDialog.OverwritePrompt = true;

            // 显示对话框并获取结果
            bool? result = saveFileDialog.ShowDialog();

            // 如果用户点击了保存按钮
            if (result == true)
            {
                return saveFileDialog.FileName;
            }
            return null;
        }
        public void ExportToExcel(DataTable data, IXLWorksheet ws)
        {
            // 写入列头（通过反射获取属性名）
            //var properties = typeof(T).GetProperties();
            //for (int i = 0; i < properties.Length; i++)
            //{
            //    ws.Cells[1, i + 1].Value = properties[i].Name;
            //}

            //// 写入数据
            //for (int row = 0; row < data.Count; row++)
            //{
            //    for (int col = 0; col < properties.Length; col++)
            //    {
            //        worksheet.Cells[row + 2, col + 1].Value = properties[col].GetValue(data[row]);
            //    }
            //}
            ws.Cell(1, 1).InsertTable(data); // 自动包含列头
        }
    #endregion

    private RelayCommand<string>? statis_cmd;
        public RelayCommand<string> Statis_cmd
        {
            get
            {
                if (statis_cmd == null)
                {
                    statis_cmd = new RelayCommand<string>((p) => Statis_click(p));
                }
                return statis_cmd;
            }
        }
        private void Statis_click(string obj)
        {
            switch (obj)
            {
                case "start_statis":
                    Statis();
                    break;
            }
        }

        #region 查询数据库
        private void StatisPanel(List<PanelDataModel> panels)
        {
            ProgressMsg.CurrentJobCount = 0;
            ProgressMsg.JobName = "统计Panel";
            ProgressMsg.AllJobCount = panels.Count;
            ProgressMsg.Cmd = ProgressMsgType.go;
            Messenger.Default.Send<ProgressMsg>(ProgressMsg, ProgressMsg.Progress_Msg_Key);
            if (!MachineStatisInfos.ContainsKey(MachineStatisModel.All_panels))
            {
                MachineStatisInfos[MachineStatisModel.All_panels] = new MachineStatisModel()
                {
                    MachineName = MachineStatisModel.All_panels,
                    TotalPanels = panels.Count
                };
                Application.Current.Dispatcher.Invoke(() =>
                {
                    MachineNameList.Add(MachineStatisModel.All_panels);
                });
            }
            int all_count = panels.Count;
            foreach (var panel in panels)
            {
                if (!MachineStatisInfos.ContainsKey(panel.RecipeCode))
                {
                    MachineStatisInfos[panel.RecipeCode] = new MachineStatisModel() {
                        MachineName = panel.RecipeCode,
                        TotalPanels = 1};
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        MachineNameList.Add(panel.RecipeCode);
                    });
                }
                else
                {
                    MachineStatisInfos[panel.RecipeCode].TotalPanels += 1;
                }
                MachineStatisInfos[panel.RecipeCode].AddPanel(panel);
                MachineStatisInfos[MachineStatisModel.All_panels].AddPanel(panel);

                ProgressMsg.CurrentJobCount++;
                ProgressMsg.Cmd = ProgressMsgType.go;
                Messenger.Default.Send<ProgressMsg>(ProgressMsg, ProgressMsg.Progress_Msg_Key);
            }
        }
        private void StatisBoard(List<BoardDataModel> boards)
        {
            ProgressMsg.CurrentJobCount = 0;
            ProgressMsg.JobName = "统计Board";
            ProgressMsg.AllJobCount = boards.Count;
            ProgressMsg.Cmd = ProgressMsgType.go;
            Messenger.Default.Send<ProgressMsg>(ProgressMsg, ProgressMsg.Progress_Msg_Key);

            foreach (var board in boards)
            {
                MachineStatisInfos[board.RecipeCode].AddBoard(board.State);
                MachineStatisInfos[MachineStatisModel.All_panels].AddBoard(board.State);

                ProgressMsg.CurrentJobCount++;
                ProgressMsg.Cmd = ProgressMsgType.go;
                Messenger.Default.Send<ProgressMsg>(ProgressMsg, ProgressMsg.Progress_Msg_Key);
            }
        }
        private ProgressMsg? ProgressMsg;
        private bool is_static_over = true;
        private void Statis()
        {
            if (!is_static_over) return;

            is_static_over = false;
            MachineNameList.Clear();
            MachineStatisInfos.Clear();
            Messenger.Default.Send("开始统计", "operator_log");

            Task.Run(() =>
            {
                ProgressMsg = new ProgressMsg()
                {
                    Cmd = ProgressMsgType.Start,
                    AllJobCount = -1,
                    CurrentJobCount = 0,
                    NotifyTextX = "查询中",
                    Title = "统计进度",
                };

                Messenger.Default.Send<ProgressMsg>(ProgressMsg, ProgressMsg.Progress_Msg_Key);
                

                DatabaseHelper databaseHelper = new DatabaseHelper();
                StartTime = StartTime.AddHours(StartTime_hour - StartTime.Hour);
                EndTime = EndTime.AddHours(EndTime_hour - EndTime.Hour);

                var panels = databaseHelper.GetAllPanel(StartTime, EndTime, SerachMachineName, ref ProgressMsg);
                if (panels != null && panels.Count > 0)
                {
                    StatisPanel(panels);

                    StatisBoard(databaseHelper.GetBoards(panels, ref ProgressMsg));

                    foreach (var item in MachineStatisInfos)
                    {
                        item.Value.EndAdd();
                    }

                    CurrentStatisModel = MachineStatisInfos.Values.FirstOrDefault();
                    if (CurrentStatisModel != null)
                        CurrentMachineName = CurrentStatisModel.MachineName ?? "";
                }
                ProgressMsg.CurrentJobCount = 0;
                ProgressMsg.JobName = "统计完成";
                ProgressMsg.AllJobCount = 0;
                ProgressMsg.Cmd = ProgressMsgType.end;
                Messenger.Default.Send<ProgressMsg>(ProgressMsg, ProgressMsg.Progress_Msg_Key);

                Messenger.Default.Send("统计完成", "operator_log");

                is_static_over = true;
            });
        }
        #endregion
    }
}
